class Service {
  constructor(config) {
    return this.init(config);
  }
  queryToUrl(query = {}) {
    if (query) {
      let keys = Object.keys(query);
      const querys = keys.map((key) => {
        return `${key}=${query[key]}`;
      });
      if (querys.length) {
        return "?" + querys.join("&");
      }
    }
    return "";
  }
  getConfig(config) {
    let params = {
      method: config.method || "GET",
      headers: {
        "Content-Type": "application/json",
        ...config.headers,
      },
    };
    let url = "";
    url = config.url;
    if (params.method === "GET") {
      url += this.queryToUrl(config.data);
    }
    if (params.method === "POST") {
      const type = Object.prototype.toString.call(config.data || {});
      if (type === "[object Object]") {
        params.body = JSON.stringify(config.data);
      }

      if (type === "[object FormData]") {
        params.body = config.data;
      }
    }
    params.url = url;
    return params;
  }
  init(config) {
    const { url, ...params } = this.getConfig(config);
    const raceFnArr = [];
    const controller = new AbortController();
    params.signal = controller.signal;
    const fetchFn = (resolve, reject) => {
      fetch(url, params)
        .then((res) => {
          const type = res.headers.get("Content-Type");
          switch (type) {
            case "application/json":
              return res.json();
            default:
              return res.text();
          }
        })
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    };
    raceFnArr.push(fetchFn);
    if (typeof config.timeout !== "undefined") {
      const fn = function (resolve, reject) {
        setTimeout(() => {
          controller.abort();
          reject("timeout");
        }, config.timeout);
      };
      raceFnArr.push(fn);
    }
    return Promise.race(raceFnArr.map((fn) => new Promise(fn)));
  }
}

function service(config) {
  return new Service(config);
}

service({
  url: "http://localhost:3000/post",
  method: "POST",
  data: {
    user:'user1'
  },
})
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.error(err);
  });
